package com.coolingme.Method;

import com.coolingme.domain.Person;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Method中的方法
 *
 * @author wangyue
 * @date 2019/3/16 14:18
 */
public class PersonMethodTest {

    public static void main(String[] args) {
        try {
            // 通过Person类获取clazz
            Class clazz = Person.class;
            // 创建类的对象
            Person person = (Person) clazz.newInstance();

            // 1.通过clazz的 方法名和参数类型 获取method对象
            // 获取共有方法(自身+父类)
            // 第一个参数：方法名    第二个参数(可不填)：方法参数类型   方法有重载
            Method m = clazz.getMethod("speak", Integer.class);
            Method m2 = clazz.getMethod("speak");

            // 使用方法
            // 第一个参数：类对象    第二个参数：方法参数值
            int result = (Integer) m.invoke(person, 23);
            System.out.println(result);

            // 获取全部方法 获取共有方法(自身+父类)
            Method[] ms = clazz.getMethods();
            System.out.println("自身+父类的所有方法：");
            for (Method ms0 : ms) {
                System.out.println(ms0.getName());
            }

            System.out.println("--------------");

            // 获取方法(自身的 共有/私有)
            Method privteM = clazz.getDeclaredMethod("getWeight", Integer.class);
            System.out.println(privteM.getName());

            // 调用私有方法
            // 强吻，设置使用权限
            privteM.setAccessible(true);
            // 方法对象.invoke(类对象,参数)
            String resultPrivateM = (String) privteM.invoke(person, 65);
            System.out.println(resultPrivateM);

            // 获取所有方法(自身的 共有/私有)
            Method[] privateMs = clazz.getDeclaredMethods();
            System.out.println("自身的 共有/私有所有方法：");
            for (Method privateMs0 : privateMs) {
                System.out.println(privateMs0.getName());
            }

            System.out.println("--------------");


            // 2.获取方法的修饰符（权限+特征）
            int modifiers = m.getModifiers();
            System.out.println(modifiers);

            // 3.获取方法的返回值类型
            Class mrt = m.getReturnType();
            System.out.println(mrt.getName());

            // 4.获取方法的名称
            String nName = m.getName();
            System.out.println(nName);

            // 5.获取方法的参数列表类型
            Class[] mpt = m.getParameterTypes();
            for (Class c : mpt) {
                System.out.println(c.getName());
            }

            // 6.获取方法所抛出异常的类型
            Class[] met = m.getExceptionTypes();
            for (Class c : met) {
                System.out.println(c.getName());
            }
            System.out.println("-------------");

            // 7.获取父类
            Class<?> clazz2 = m.getDeclaringClass();
            System.out.println(clazz2.getName());


        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
